#include "Similarity.h"
#include <cmath>
#include <QDebug>

float Similarity::calculate(const QVector<float>& vec1, const QVector<float>& vec2) {
    qDebug() << "计算相似度,使用方法:";
    #if SIMILARITY_METHOD == SIMILARITY_METHOD_COSINE
        qDebug() << "余弦相似度";
        return cosineSimilarity(vec1, vec2);
    #elif SIMILARITY_METHOD == SIMILARITY_METHOD_EUCLIDEAN
        qDebug() << "欧几里得距离";
        return 1.0f / (1.0f + euclideanDistance(vec1, vec2));
    #elif SIMILARITY_METHOD == SIMILARITY_METHOD_COMBINED
        qDebug() << "组合方法";
        return combinedSimilarity(vec1, vec2);
    #else
        #error "Invalid SIMILARITY_METHOD"
    #endif
}

float Similarity::cosineSimilarity(const QVector<float>& vec1, const QVector<float>& vec2) {
    qDebug() << "计算余弦相似度";
    float dotProduct = 0.0f;
    float norm1 = 0.0f;
    float norm2 = 0.0f;
    
    for (int i = 0; i < vec1.size(); ++i) {
        dotProduct += vec1[i] * vec2[i];
        norm1 += vec1[i] * vec1[i];
        norm2 += vec2[i] * vec2[i];
    }
    
    float similarity = dotProduct / (std::sqrt(norm1) * std::sqrt(norm2));
    qDebug() << "余弦相似度结果:" << similarity;
    return similarity;
}

float Similarity::euclideanDistance(const QVector<float>& vec1, const QVector<float>& vec2) {
    qDebug() << "计算欧几里得距离";
    float sum = 0.0f;
    for (int i = 0; i < vec1.size(); ++i) {
        float diff = vec1[i] - vec2[i];
        sum += diff * diff;
    }
    float distance = std::sqrt(sum);
    qDebug() << "欧几里得距离结果:" << distance;
    return distance;
}

float Similarity::combinedSimilarity(const QVector<float>& vec1, const QVector<float>& vec2) {
    qDebug() << "计算组合相似度";
    float cosine = cosineSimilarity(vec1, vec2);
    float euclidean = 1.0f / (1.0f + euclideanDistance(vec1, vec2));
    float combined = (cosine + euclidean) / 2.0f;
    qDebug() << "组合相似度结果:" << combined;
    return combined;
}
